package com.zenithmind.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zenithmind.article.feign.UserFeignClient;
import com.zenithmind.article.mapper.ArticleMapper;
import com.zenithmind.article.mapper.ArticleTagMapper;
import com.zenithmind.article.mapper.CategoryMapper;
import com.zenithmind.article.mapper.TagMapper;
import com.zenithmind.article.pojo.domain.*;
import com.zenithmind.article.pojo.vo.ArticleVO;
import com.zenithmind.article.pojo.vo.AuthorVO;
import com.zenithmind.article.pojo.vo.UserVO;
import com.zenithmind.article.service.ArticleQueryService;
import com.zenithmind.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.zenithmind.common.annotation.DataCache;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文章查询服务实现
 * 遵循单一职责原则：专注于文章查询和统计功能
 * 遵循依赖倒置原则：通过构造器注入依赖
 */
@Slf4j
@Service
public class ArticleQueryServiceImpl implements ArticleQueryService {

    private final ArticleMapper articleMapper;
    private final ArticleTagMapper articleTagMapper;
    private final CategoryMapper categoryMapper;
    private final TagMapper tagMapper;
    private final UserFeignClient userFeignClient;

    // 缓存前缀常量
    private static final String CACHE_HOT_ARTICLES_KEY = "hot_articles";
    private static final String CACHE_ARCHIVES_KEY = "article_archives";
    private static final String CACHE_ACTIVE_AUTHORS_KEY = "active_authors";

    // 构造器注入，遵循依赖倒置原则
    public ArticleQueryServiceImpl(
            ArticleMapper articleMapper,
            ArticleTagMapper articleTagMapper,
            CategoryMapper categoryMapper,
            TagMapper tagMapper,
            UserFeignClient userFeignClient) {
        this.articleMapper = articleMapper;
        this.articleTagMapper = articleTagMapper;
        this.categoryMapper = categoryMapper;
        this.tagMapper = tagMapper;
        this.userFeignClient = userFeignClient;
    }

    @Override
    @DataCache(prefix = "article", key = CACHE_HOT_ARTICLES_KEY, expireTime = 3600)
    public List<ArticleVO> getHotArticles() {
        log.info("获取热门文章");
        
        List<Article> hotArticles = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1) // 已发布
                        .orderByDesc(Article::getViewCount)
                        .orderByDesc(Article::getLikeCount)
                        .last("LIMIT 10")
        );

        return convertToVOList(hotArticles);
    }

    @Override
    @DataCache(prefix = "article", key = "'blog_hot_' + #limit", expireTime = 1800)
    public List<ArticleVO> getBlogHotArticles(Integer limit) {
        log.info("获取博客页面热门文章，限制数量: {}", limit);
        
        int actualLimit = limit != null && limit > 0 ? Math.min(limit, 20) : 5;
        
        List<Article> hotArticles = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1) // 已发布
                        .eq(Article::getIsRecommend, true) // 推荐文章
                        .orderByDesc(Article::getViewCount)
                        .orderByDesc(Article::getCreateTime)
                        .last("LIMIT " + actualLimit)
        );

        return convertToVOList(hotArticles);
    }

    @Override
    @DataCache(prefix = "article", key = "'active_authors_' + #limit", expireTime = 3600)
    public List<AuthorVO> getActiveAuthors(Integer limit) {
        log.info("获取活跃作者，限制数量: {}", limit);
        
        int actualLimit = limit != null && limit > 0 ? Math.min(limit, 10) : 5;
        
        // 查询最近30天内发布文章最多的作者
        LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);
        
        // 简化查询，先获取所有已发布的文章，然后在内存中统计
        List<Article> recentArticles = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1)
                        .ge(Article::getCreateTime, thirtyDaysAgo)
        );

        // 按用户分组统计
        Map<String, List<Article>> userArticleMap = recentArticles.stream()
                .collect(Collectors.groupingBy(Article::getUserId));

        List<Map<String, Object>> authorStats = userArticleMap.entrySet().stream()
                .map(entry -> {
                    String userId = entry.getKey();
                    List<Article> userArticles = entry.getValue();
                    Map<String, Object> stat = new HashMap<>();
                    stat.put("user_id", userId);
                    stat.put("article_count", (long) userArticles.size());
                    stat.put("total_views", userArticles.stream().mapToLong(Article::getViewCount).sum());
                    return stat;
                })
                .sorted((a, b) -> Long.compare((Long) b.get("article_count"), (Long) a.get("article_count")))
                .limit(actualLimit)
                .collect(Collectors.toList());

        return convertToAuthorVOList(authorStats);
    }

    @Override
    @DataCache(prefix = "article", key = CACHE_ARCHIVES_KEY, expireTime = 7200)
    public List<ArticleVO> getArticleArchives() {
        log.info("获取文章归档");
        
        List<Article> archives = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1) // 已发布
                        .orderByDesc(Article::getCreateTime)
                        .last("LIMIT 100") // 限制归档数量
        );

        return convertToVOList(archives);
    }

    @Override
    public List<ArticleVO> getRelatedArticles(String articleId) {
        log.info("获取相关文章，文章ID: {}", articleId);
        
        if (StringUtils.isBlank(articleId)) {
            return Collections.emptyList();
        }

        // 获取当前文章信息
        Article currentArticle = articleMapper.selectById(articleId);
        if (currentArticle == null) {
            return Collections.emptyList();
        }

        // 基于分类和标签查找相关文章
        List<Article> relatedArticles = findRelatedArticlesByCategory(currentArticle);
        
        if (relatedArticles.size() < 5) {
            // 如果基于分类的相关文章不够，补充基于标签的相关文章
            List<Article> tagRelatedArticles = findRelatedArticlesByTags(articleId);
            relatedArticles.addAll(tagRelatedArticles);
        }

        // 去重并限制数量
        List<Article> uniqueRelated = relatedArticles.stream()
                .filter(article -> !article.getId().equals(articleId))
                .distinct()
                .limit(5)
                .collect(Collectors.toList());

        return convertToVOList(uniqueRelated);
    }

    @Override
    @DataCache(prefix = "article", key = "'recommended_' + #limit", expireTime = 1800)
    public List<ArticleVO> getRecommendedArticles(Integer limit) {
        log.info("获取推荐文章，限制数量: {}", limit);
        
        int actualLimit = limit != null && limit > 0 ? Math.min(limit, 10) : 5;
        
        List<Article> recommended = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1) // 已发布
                        .eq(Article::getIsRecommend, true) // 推荐文章
                        .orderByDesc(Article::getCreateTime)
                        .last("LIMIT " + actualLimit)
        );

        return convertToVOList(recommended);
    }

    @Override
    @DataCache(prefix = "article", key = "'latest_' + #limit", expireTime = 600)
    public List<ArticleVO> getLatestArticles(Integer limit) {
        log.info("获取最新文章，限制数量: {}", limit);
        
        int actualLimit = limit != null && limit > 0 ? Math.min(limit, 10) : 5;
        
        List<Article> latest = articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getStatusCode, 1) // 已发布
                        .orderByDesc(Article::getCreateTime)
                        .last("LIMIT " + actualLimit)
        );

        return convertToVOList(latest);
    }

    /**
     * 基于分类查找相关文章
     */
    private List<Article> findRelatedArticlesByCategory(Article currentArticle) {
        if (StringUtils.isBlank(currentArticle.getCategoryId())) {
            return Collections.emptyList();
        }

        return articleMapper.selectList(
                new LambdaQueryWrapper<Article>()
                        .eq(Article::getCategoryId, currentArticle.getCategoryId())
                        .eq(Article::getStatusCode, 1)
                        .ne(Article::getId, currentArticle.getId())
                        .orderByDesc(Article::getViewCount)
                        .last("LIMIT 3")
        );
    }

    /**
     * 基于标签查找相关文章
     */
    private List<Article> findRelatedArticlesByTags(String articleId) {
        // 获取当前文章的标签
        List<ArticleTag> articleTags = articleTagMapper.selectList(
                new LambdaQueryWrapper<ArticleTag>()
                        .eq(ArticleTag::getArticleId, articleId)
                        .eq(ArticleTag::getStatusCode, 1)
        );

        if (articleTags.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> tagIds = articleTags.stream()
                .map(ArticleTag::getTagId)
                .collect(Collectors.toList());

        // 查找有相同标签的其他文章
        List<ArticleTag> relatedArticleTags = articleTagMapper.selectList(
                new LambdaQueryWrapper<ArticleTag>()
                        .in(ArticleTag::getTagId, tagIds)
                        .ne(ArticleTag::getArticleId, articleId)
                        .eq(ArticleTag::getStatusCode, 1)
        );

        if (relatedArticleTags.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> relatedArticleIds = relatedArticleTags.stream()
                .map(ArticleTag::getArticleId)
                .distinct()
                .collect(Collectors.toList());

        return articleMapper.selectBatchIds(relatedArticleIds).stream()
                .filter(article -> article.getStatusCode() == 1)
                .limit(3)
                .collect(Collectors.toList());
    }

    /**
     * 转换为 VO 列表
     */
    private List<ArticleVO> convertToVOList(List<Article> articles) {
        if (articles == null || articles.isEmpty()) {
            return Collections.emptyList();
        }

        return articles.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    /**
     * 转换为 VO
     */
    private ArticleVO convertToVO(Article article) {
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(article, articleVO);
        
        // 设置状态码
        articleVO.setStatus(article.getStatusCode());
        
        // 获取用户信息
        try {
            Result<UserVO> userResult = userFeignClient.getUserById(article.getUserId());
            if (userResult != null && userResult.isSuccess() && userResult.getData() != null) {
                articleVO.setUserVo(userResult.getData());
            }
        } catch (Exception e) {
            log.warn("获取用户信息失败: {}", article.getUserId(), e);
        }

        // 获取分类信息
        if (StringUtils.isNotBlank(article.getCategoryId())) {
            Category category = categoryMapper.selectById(article.getCategoryId());
            articleVO.setCategory(category);
        }

        // 获取标签信息
        List<Tag> tags = getArticleTags(article.getId());
        articleVO.setTag(tags);

        return articleVO;
    }

    /**
     * 转换为作者 VO 列表
     */
    private List<AuthorVO> convertToAuthorVOList(List<Map<String, Object>> authorStats) {
        return authorStats.stream()
                .map(this::convertToAuthorVO)
                .collect(Collectors.toList());
    }

    /**
     * 转换为作者 VO
     */
    private AuthorVO convertToAuthorVO(Map<String, Object> stats) {
        String userId = (String) stats.get("user_id");
        Long articleCount = (Long) stats.get("article_count");
        Long totalViews = (Long) stats.get("total_views");

        AuthorVO authorVO = new AuthorVO();
        authorVO.setUserId(userId);
        authorVO.setArticleCount(articleCount != null ? articleCount.intValue() : 0);
        authorVO.setTotalViews(totalViews != null ? totalViews.intValue() : 0);

        // 获取用户信息
        try {
            Result<UserVO> userResult = userFeignClient.getUserById(userId);
            if (userResult != null && userResult.isSuccess() && userResult.getData() != null) {
                UserVO userVO = userResult.getData();
                authorVO.setUsername(userVO.getUsername());
                authorVO.setAvatar(userVO.getAvatar());
            }
        } catch (Exception e) {
            log.warn("获取作者信息失败: {}", userId, e);
        }

        return authorVO;
    }

    /**
     * 获取文章标签
     */
    private List<Tag> getArticleTags(String articleId) {
        List<ArticleTag> articleTags = articleTagMapper.selectList(
                new LambdaQueryWrapper<ArticleTag>()
                        .eq(ArticleTag::getArticleId, articleId)
                        .eq(ArticleTag::getStatusCode, 1)
        );

        if (articleTags.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> tagIds = articleTags.stream()
                .map(ArticleTag::getTagId)
                .collect(Collectors.toList());

        return tagMapper.selectBatchIds(tagIds);
    }
}
